package Othello;

import java.util.Scanner;
import java.util.stream.Stream;

public class OthelloGame {
    private CheckBoard board;
    private ChessType currentPlayer;
    private Scanner scanner;

    public OthelloGame() {
        board = new CheckBoard(8, 8);
        scanner = new Scanner(System.in);
        initializeBoard();
        currentPlayer = ChessType.black;
    }

    private void initializeBoard() {
        // 初始布局：黑棋在4D(3,3)和5E(4,4)，白棋在4E(4,3)和5D(3,4)
        board.putChess(3, 3, ChessType.white);
        board.putChess(3, 4, ChessType.black);
        board.putChess(4, 3, ChessType.black);
        board.putChess(4, 4, ChessType.white);
    }

    public void startGame() {
        while (gameContinues()) {
            printBoard();
            if (hasValidMoves()) {
                processPlayerMove();
            } else {
                System.out.println(currentPlayer + " 无合法走法，跳过回合");
            }
            switchPlayer();
        }
        printFinalResult();
    }

    private boolean gameContinues() {
        return Stream.of(ChessType.black, ChessType.white)
                .anyMatch(player -> hasValidMoves(player))
                && !boardIsFull();
    }

    private boolean boardIsFull() {
        return board.stream().noneMatch(c -> c.getChessType() == ChessType.blank);
    }

    private boolean hasValidMoves(ChessType player) {
        return board.stream()
                .filter(c -> c.getChessType() == ChessType.blank)
                .anyMatch(c -> board.isValidMove(new Point(c.getX(), c.getY()), player));
    }

    private boolean hasValidMoves() {
        return hasValidMoves(currentPlayer);
    }

    private void processPlayerMove() {
        while (true) {
            System.out.print(currentPlayer + " 方落子（格式：列行，如D3）: ");
            Point move = parseInput(scanner.nextLine().trim().toUpperCase());
            if (move != null && isValidMove(move)) {
                board.putChess(move, currentPlayer);
                return;
            }
            System.out.println("无效走法，请重新输入");
        }
    }

    private Point parseInput(String input) {
        if (input.length() != 2)
            return null;
        int x = input.charAt(0) - 'A';
        int y = input.charAt(1) - '1';
        return (x >= 0 && x < 8 && y >= 0 && y < 8) ? new Point(x, y) : null;
    }

    private boolean isValidMove(Point p) {
        return board.getChess(p.getX(), p.getY()) == ChessType.blank
                && board.isValidMove(p, currentPlayer);
    }

    private void switchPlayer() {
        currentPlayer = currentPlayer.reverse();
    }

    private void printBoard() {
        System.out.print("  ");
        for (char c = 'A'; c <= 'H'; c++) {
            System.out.print(c + " ");
        }
        System.out.println();

        for (int y = 0; y < 8; y++) {
            System.out.print((y + 1) + " ");
            for (int x = 0; x < 8; x++) {
                ChessType type = board.getChess(x, y);
                System.out.print(typeToSymbol(type) + " ");
            }
            System.out.println(y + 1);
        }

        System.out.print("  ");
        for (char c = 'A'; c <= 'H'; c++) {
            System.out.print(c + " ");
        }
        System.out.println();
    }

    private String typeToSymbol(ChessType type) {
        return "";
        // return switch (type) {
        // case black -> "⚫";
        // case white -> "⚪";
        // default -> "⬜";
        // };
    }

    private void printFinalResult() {
        long blackCount = countPieces(ChessType.black);
        long whiteCount = countPieces(ChessType.white);

        System.out.println("游戏结束！");
        System.out.println("黑方: " + blackCount + " 子");
        System.out.println("白方: " + whiteCount + " 子");

        if (blackCount > whiteCount)
            System.out.println("黑方获胜！");
        else if (whiteCount > blackCount)
            System.out.println("白方获胜！");
        else
            System.out.println("平局！");
    }

    private long countPieces(ChessType type) {
        return board.stream().filter(c -> c.getChessType() == type).count();
    }

    public static void main(String[] args) {
        new OthelloGame().startGame();
    }
}